home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
10,000 Great Games
/
10,000 Great Games.iso
/
Product
/
66
/
data1.cab
/
Source_Files
/
Src
/
Char.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-16
|
18KB
|
898 lines
#include "stdafx.h"
cCharacter::cCharacter(cProperties *_orig)
: cGameObject(_orig)
{
// Get animations
orig->get_sequence("WALK LEFT", walk_left_seq);
orig->get_sequence("WALK RIGHT", walk_right_seq);
orig->get_sequence("WALK LEFT RIGHT", walk_left_right_seq);
orig->get_sequence("WALK FIRE LEFT", walk_fire_left_seq);
orig->get_sequence("WALK FIRE RIGHT", walk_fire_right_seq);
orig->get_sequence("WALK FIRE UP", walk_fire_up_seq);
orig->get_sequence("JUMP LEFT", jump_left_seq);
orig->get_sequence("JUMP RIGHT", jump_right_seq);
orig->get_sequence("JUMP LEFT RIGHT", jump_left_right_seq);
orig->get_sequence("JUMP FIRE LEFT", jump_fire_left_seq);
orig->get_sequence("JUMP FIRE RIGHT", jump_fire_right_seq);
orig->get_sequence("JUMP FIRE UP LEFT", jump_fire_up_left_seq);
orig->get_sequence("JUMP FIRE UP RIGHT", jump_fire_up_right_seq);
orig->get_sequence("DUCK LEFT", duck_left_seq);
orig->get_sequence("DUCK RIGHT", duck_right_seq);
orig->get_sequence("DUCK LEFT RIGHT", duck_left_right_seq);
orig->get_sequence("DUCK FIRE LEFT", duck_fire_left_seq);
orig->get_sequence("DUCK FIRE RIGHT", duck_fire_right_seq);
orig->get_sequence("JET LEFT", jet_left_seq);
orig->get_sequence("JET RIGHT", jet_right_seq);
orig->get_sequence("JET LEFT RIGHT", jet_left_right_seq);
orig->get_sequence("JET FIRE LEFT", jet_fire_left_seq);
orig->get_sequence("JET FIRE RIGHT", jet_fire_right_seq);
orig->get_sequence("JET FIRE UP LEFT", jet_fire_up_left_seq);
orig->get_sequence("JET FIRE UP RIGHT", jet_fire_up_right_seq);
orig->get_sequence("JET ON LEFT", jet_on_left_seq);
orig->get_sequence("JET ON RIGHT", jet_on_right_seq);
orig->get_sequence("JET OFF LEFT", jet_off_left_seq);
orig->get_sequence("JET OFF RIGHT", jet_off_right_seq);
orig->get_sequence("KICK LEFT", kick_left_seq);
orig->get_sequence("KICK RIGHT", kick_right_seq);
orig->get_sequence("STUNNED", stunned_seq);
orig->get_sequence("CAPTURED", captured_seq);
orig->get_sequence("CLIMBING", climbing_seq);
// Set boundaries
orig->get_circles("STANDING", &bounds_standing);
orig->get_circles("DUCKED", &bounds_ducked);
// Circles for kick
orig->get_circles("KICK LEFT", &kick_left_circle);
orig->get_circles("KICK RIGHT", &kick_right_circle);
// Set spots
orig->get_spots("WALK FIRE LEFT", &walk_fire_left_spot);
orig->get_spots("WALK FIRE RIGHT", &walk_fire_right_spot);
orig->get_spots("WALK FIRE UP", &walk_fire_up_spot);
orig->get_spots("JUMP FIRE LEFT", &jump_fire_left_spot);
orig->get_spots("JUMP FIRE RIGHT", &jump_fire_right_spot);
orig->get_spots("JUMP FIRE UP LEFT", &jump_fire_up_left_spot);
orig->get_spots("JUMP FIRE UP RIGHT", &jump_fire_up_right_spot);
orig->get_spots("JET FIRE LEFT", &jet_fire_left_spot);
orig->get_spots("JET FIRE RIGHT", &jet_fire_right_spot);
orig->get_spots("JET FIRE UP LEFT", &jet_fire_up_left_spot);
orig->get_spots("JET FIRE UP RIGHT", &jet_fire_up_right_spot);
orig->get_spots("DUCK FIRE LEFT", &duck_fire_left_spot);
orig->get_spots("DUCK FIRE RIGHT", &duck_fire_right_spot);
orig->get_spots("FIRE DOWN", &fire_down_spot);
// Get sounds
orig->get_soundsequence("GOT HIT", snd_gothit);
// Clear weapons
weapon = 0;
weapon_down = 0;
// Reset score counters
deaths = 0;
stuns = 0;
shots_fired = 0;
// Set text stuff
text_above_char = new cText (&texts);
text_above_char->set_centered(TRUE);
// Setup other variables
influenced_by_catapult = TRUE;
influenced_by_inpenetrable = TRUE;
// Revive character and put it in a bubble
revive();
}
void cCharacter::revive()
{
// Set some variables
stop_movement();
ay = GRAVITY;
armor = orig->params->get_int("*ARMOR", 100);
ducked = FALSE;
circle_bounds = bounds_standing;
standing = FALSE;
climbing = FALSE;
captured = 0;
dead = FALSE;
jetpack_active = FALSE;
jetpack_time = JETPACK_TIME;
stunned = 0;
firing = 0;
ignore_platforms = 0;
next_stun_time = 2 * sec;
invulnerable = CHAR_INVULNERABLE;
last_move = CHAR_LEFT;
horiz_speed = 0;
set_last_in_sequence(jump_left_seq);
// Weapon is standard gun
weapon->delete_list();
new cInventoryBullet(&weapon);
weapon_down->delete_list();
}
cCharacter::~cCharacter()
{
// Delete weapons
weapon->delete_list();
weapon_down->delete_list();
// Delete boundaries
bounds_standing->delete_list();
bounds_ducked->delete_list();
// Delete circles
kick_left_circle->delete_list();
kick_right_circle->delete_list();
// Delete spots
walk_fire_left_spot->delete_list();
walk_fire_right_spot->delete_list();
walk_fire_up_spot->delete_list();
jump_fire_left_spot->delete_list();
jump_fire_right_spot->delete_list();
jump_fire_up_left_spot->delete_list();
jump_fire_up_right_spot->delete_list();
duck_fire_left_spot->delete_list();
duck_fire_right_spot->delete_list();
jet_fire_left_spot->delete_list();
jet_fire_right_spot->delete_list();
jet_fire_up_left_spot->delete_list();
jet_fire_up_right_spot->delete_list();
fire_down_spot->delete_list();
// Delete text
delete text_above_char;
}
void cCharacter::set_horiz_speed(int new_speed)
{
// First substract old speed
vx -= (fix)horiz_speed;
// Add new speed
vx += new_speed;
// Remember new speed
horiz_speed = new_speed;
}
void cCharacter::walk_turn_left()
{
if (last_move != CHAR_LEFT)
set_inverse_sequence(walk_left_right_seq);
last_move = CHAR_LEFT;
}
void cCharacter::walk_left()
{
walk_turn_left();
set_horiz_speed(-CHAR_WALK_SPEED);
}
void cCharacter::walk_turn_right()
{
if (last_move != CHAR_RIGHT)
set_sequence(walk_left_right_seq);
last_move = CHAR_RIGHT;
}
void cCharacter::walk_right()
{
walk_turn_right();
set_horiz_speed(CHAR_WALK_SPEED);
}
void cCharacter::walk_h_halt()
{
cAnimation c = get_sequence();
if (c.start_frame == walk_left_seq.start_frame || c.start_frame == walk_right_seq.start_frame)
stop_animation();
set_horiz_speed(0);
}
void cCharacter::climb_turn_left()
{
last_move = CHAR_LEFT;
}
void cCharacter::climb_left()
{
climb_turn_left();
set_horiz_speed(-CHAR_CLIMB_SPEED);
}
void cCharacter::climb_turn_right()
{
last_move = CHAR_RIGHT;
}
void cCharacter::climb_right()
{
last_move = CHAR_RIGHT;
set_horiz_speed(CHAR_CLIMB_SPEED);
}
void cCharacter::climb_up()
{
vy = CHAR_CLIMB_SPEED;
}
void cCharacter::climb_down()
{
vy = -CHAR_CLIMB_SPEED;
}
void cCharacter::climb_h_halt()
{
set_horiz_speed(0);
}
void cCharacter::climb_v_halt()
{
vy = 0;
}
void cCharacter::jet_on()
{
if (!jetpack_active && jetpack_time > 0)
{
ay = 0;
vy = 0;
jetpack_active = TRUE;
jetpack_timer = 0;
set_sequence(last_move == CHAR_LEFT? jet_on_left_seq:jet_on_right_seq);
}
}
void cCharacter::jet_off()
{
if (jetpack_active)
{
ay = GRAVITY;
jetpack_active = FALSE;
set_sequence(last_move == CHAR_LEFT? jet_off_left_seq:jet_off_right_seq);
}
}
void cCharacter::jet_turn_left()
{
if (last_move != CHAR_LEFT)
set_inverse_sequence(jet_left_right_seq);
last_move = CHAR_LEFT;
}
void cCharacter::jet_left()
{
jet_turn_left();
set_horiz_speed(-JETPACK_SPEED);
}
void cCharacter::jet_turn_right()
{
if (last_move != CHAR_RIGHT)
set_sequence(jet_left_right_seq);
last_move = CHAR_RIGHT;
}
void cCharacter::jet_right()
{
jet_turn_right();
set_horiz_speed(JETPACK_SPEED);
}
void cCharacter::jet_up()
{
vy = JETPACK_SPEED;
}
void cCharacter::jet_down()
{
vy = -JETPACK_SPEED;
}
void cCharacter::jet_h_halt()
{
set_horiz_speed(0);
}
void cCharacter::jet_v_halt()
{
vy = 0;
}
void cCharacter::jump()
{
stand();
vy = CHAR_JUMP_SPEED;
set_sequence(last_move == CHAR_LEFT? jump_left_seq:jump_right_seq);
}
void cCharacter::jump_turn_left()
{
if (last_move != CHAR_LEFT)
set_inverse_sequence(jump_left_right_seq);
last_move = CHAR_LEFT;
}
void cCharacter::jump_left()
{
jump_turn_left();
set_horiz_speed(-CHAR_WALK_SPEED);
}
void cCharacter::jump_turn_right()
{
if (last_move != CHAR_RIGHT)
set_sequence(jump_left_right_seq);
last_move = CHAR_RIGHT;
}
void cCharacter::jump_right()
{
jump_turn_right();
set_horiz_speed(CHAR_WALK_SPEED);
}
void cCharacter::jump_h_halt()
{
set_horiz_speed(0);
}
void cCharacter::duck()
{
if (standing && !ducked)
{
ducked = TRUE;
circle_bounds = bounds_ducked;
set_horiz_speed(0);
set_sequence(last_move == CHAR_LEFT? duck_left_seq:duck_right_seq);
}
}
void cCharacter::duck_left()
{
if (last_move != CHAR_LEFT)
set_inverse_sequence(duck_left_right_seq);
last_move = CHAR_LEFT;
}
void cCharacter::duck_right()
{
if (last_move != CHAR_RIGHT)
set_sequence(duck_left_right_seq);
last_move = CHAR_RIGHT;
}
void cCharacter::stand()
{
circle_bounds = bounds_standing;
if (ducked)
{
ducked = FALSE;
set_inverse_sequence(last_move == CHAR_LEFT? duck_left_seq:duck_right_seq);
add_last_in_sequence(last_move == CHAR_LEFT? walk_left_seq:walk_right_seq);
}
}
void cCharacter::fire()
{
cCharacter *ch;
cCircle *c;
if (weapon == 0 || firing)
return;
// Increase shots fired
shots_fired++;
// Check kick distance
c = last_move == CHAR_LEFT? kick_left_circle:kick_right_circle;
ch = (cCharacter *)check_radial_boundaries(c, players);
if (ch != 0 && captured == 0 && ch->captured == 0)
{
firing = CHAR_KICK_DLY;
int was_active = ch->is_active();
// Do kick and push
ch->push(angle(c->x, 10), CHAR_KICK_POWER);
ch->hit(CHAR_KICK_APOWER);
// Create effect and set animation
new cEffect (x + c->x, y - c->y, orig, "KICK EFFECT");
set_sequence(last_move == CHAR_LEFT? kick_left_seq:kick_right_seq);
// Award points if other character was active
if (was_active)
modify_score(30 + (ch->is_active()? 0 : 50), ch);
}
else
{
firing = weapon->fire_delay;
if (last_move == CHAR_LEFT)
{
if (captured != 0)
{
delete captured;
}
else if (jetpack_active)
{
set_sequence(jet_fire_left_seq);
weapon->fire(jet_fire_left_spot, x, y, 128, this);
}
else if (ducked)
{
set_sequence(duck_fire_left_seq);
weapon->fire(duck_fire_left_spot, x, y, 128, this);
}
else if (standing)
{
set_sequence(walk_fire_left_seq);
weapon->fire(walk_fire_left_spot, x, y, 128, this);
}
else
{
set_sequence(jump_fire_left_seq);
weapon->fire(jump_fire_left_spot, x, y, 128, this);
}
}
else
{
if (captured != 0)
{
delete captured;
}
else if (jetpack_active)
{
set_sequence(jet_fire_right_seq);
weapon->fire(jet_fire_right_spot, x, y, 0, this);
}
else if (ducked)
{
set_sequence(duck_fire_right_seq);
weapon->fire(duck_fire_right_spot, x, y, 0, this);
}
else if (standing)
{
set_sequence(walk_fire_right_seq);
weapon->fire(walk_fire_right_spot, x, y, 0, this);
}
else
{
set_sequence(jump_fire_right_seq);
weapon->fire(jump_fire_right_spot, x, y, 0, this);
}
}
}
}
void cCharacter::fire_up()
{
if (weapon == 0 || firing)
return;
// Increase shots fired
shots_fired++;
// Make sure we're standing
stand();
// Fire
firing = weapon->fire_delay;
if (captured != 0)
{
delete captured;
}
else if (jetpack_active)
{
set_sequence(last_move == CHAR_LEFT? jet_fire_up_left_seq:jet_fire_up_right_seq);
weapon->fire(last_move == CHAR_LEFT? jet_fire_up_left_spot:jet_fire_up_right_spot, x, y, 64, this);
}
else if (standing)
{
set_sequence(walk_fire_up_seq);
weapon->fire(walk_fire_up_spot, x, y, 64, this);
}
else
{
set_sequence(last_move == CHAR_LEFT? jump_fire_up_left_seq:jump_fire_up_right_seq);
weapon->fire(last_move == CHAR_LEFT? jump_fire_up_left_spot:jump_fire_up_right_spot, x, y, 64, this);
}
}
void cCharacter::fire_down()
{
if (weapon_down == 0 || firing)
return;
// Increase shots fired
shots_fired++;
// Fire down
firing = weapon_down->fire_delay;
if (captured != 0)
{
delete captured;
}
else
{
weapon_down->fire(fire_down_spot, x, y, -64, this);
}
}
void cCharacter::hit(int armor_power)
{
// If already dead do nothing
if (dead)
return;
// Auch!
set_soundsequence(snd_gothit);
// Impossible to hit?
if (stunned || invulnerable || captured != 0)
return;
// Substract value from armor
armor -= armor_power;
// Put remaining armor above player
if (armor_power > 0)
set_text_above(construct("%d%%", armor <= 0? 0:armor), sec);
// Stun if no armor left
if (armor <= 0)
{
stuns++;
modify_score(-50);
stunned = next_stun_time;
invulnerable = next_stun_time + CHAR_INVULNERABLE;
make_dirty();
stand();
jet_off();
set_horiz_speed(0);
ay = GRAVITY;
set_sequence(stunned_seq);
make_dirty();
next_stun_time += sec / 2;
armor = orig->params->get_int("*ARMOR", 100);
}
}
void cCharacter::push(fix dir, int distance, fix speed, int ignore)
{
// Check if dead
if (dead || captured != 0)
return;
if (distance != 0)
new_angular_push((fix)0.5, vpush_tx((fix)0.5, distance), apush_tx((fix)0.5, distance), dir);
if (speed != (fix)0)
add_angular_speed(speed - get_speed(dir), dir);
if (ignore > 0)
ignore_platforms = ignore;
}
void cCharacter::capture(cBubble *captor)
{
if (captured == 0)
{
captured = captor;
stand();
jet_off();
stop_movement();
set_sequence(captured_seq);
}
}
void cCharacter::release()
{
if (captured != 0)
{
captured = 0;
ay = GRAVITY;
set_animation();
}
}
void cCharacter::set_text_above(char *text, int time)
{
text_above_char->make_dirty();
text_above_char->set_text(text);
text_above_char->set_position(x, y + CHAR_TEXT_DISTANCE);
text_above_char->make_dirty();
keep_showing_text = time;
}
void cCharacter::kill_text_above()
{
text_above_char->make_dirty();
text_above_char->set_text(0);
}
void cCharacter::update_text_above()
{
if (keep_showing_text)
{
text_above_char->make_dirty();
text_above_char->set_position(x, y + CHAR_TEXT_DISTANCE);
text_above_char->make_dirty();
}
else
{
kill_text_above();
}
}
void cCharacter::set_animation()
{
if (stunned)
{
set_last_in_sequence(stunned_seq);
}
else if (captured != 0)
{
set_sequence(captured_seq);
}
else if (jetpack_active)
{
set_sequence(last_move == CHAR_RIGHT? jet_right_seq:jet_left_seq);
}
else if (climbing)
{
if (abs(vx) > (fix)1 || vy > (fix)1)
set_sequence(climbing_seq);
else if (vy < (fix)-1)
set_inverse_sequence(climbing_seq);
else
set_last_in_sequence(climbing_seq);
}
else if (ducked)
{
set_last_in_sequence(last_move == CHAR_RIGHT? duck_right_seq:duck_left_seq);
}
else if (standing)
{
if (abs(vx) > (fix)1)
set_sequence(last_move == CHAR_RIGHT? walk_right_seq:walk_left_seq);
else
set_last_in_sequence(last_move == CHAR_RIGHT? walk_right_seq:walk_left_seq);
}
else
set_last_in_sequence(last_move == CHAR_RIGHT? jump_right_seq:jump_left_seq);
}
int cCharacter::control()
{
cGameObject::control();
// Check if we're dead/dying
if (dead)
{
set_image(0);
set_position(x, surface->start);
stop_movement();
kill_text_above();
return dead_timer;
}
// Check if we're captured by something
if (captured != 0)
{
if (animation_done())
set_sequence(captured_seq);
stop_movement();
update_text_above();
return TRUE;
}
// Set transparent if invulnerable
set_colormap(invulnerable && !stunned? cmap_gray:0);
// Check inpenetrable walls
check_radial_boundaries(circle_bounds, structures, cStructure::check_inpenetrable);
// Do jetpack stuff
if (jetpack_active)
{
jetpack_time -= jetpack_timer.raw_delta();
if (jetpack_time <= 0)
{
jetpack_time = 0;
jet_off();
}
}
// Check if character is on stairs
int was_climbing = climbing;
climbing = !ignore_platforms && is_active() && !jetpack_active
&& check_radial_boundaries(circle_bounds, stairs) != 0;
if (was_climbing && !climbing && vy == (fix)CHAR_CLIMB_SPEED)
vy = CHAR_JUMP_SPEED;
if ((was_climbing && !climbing) || (!was_climbing && climbing))
stop_animation();
// Check if character landed
standing = !ignore_platforms && !jetpack_active && !climbing
&& check_resting_on_boundaries(line_bounds, structures);
if (standing)
vy = 0;
else
stand();
// Adjust vertical motion
if (climbing || jetpack_active)
ay = 0;
else
ay = GRAVITY;
// Adjust horizontal motion
ax = 0;
if (!x_on_screen())
horiz_speed = 0, vx = 0;
else if (!is_x_pushed())
vx = horiz_speed;
// Animate
if (animation_done())
set_animation();
// Set bounds
circle_bounds = !stunned && !ducked? bounds_standing:bounds_ducked;
// Die ?
if (in_water())
{
dead = TRUE;
dead_timer = 3 * sec;
armor = 0;
circle_bounds = 0;
deaths++;
modify_score(-200);
}
update_text_above();
return TRUE;
}